<?php
namespace app\common\service;

use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Ess\V20201111\EssClient;
use TencentCloud\Ess\V20201111\Models\CreateFlowRequest;
use TencentCloud\Ess\V20201111\Models\CreateDocumentRequest;
use TencentCloud\Ess\V20201111\Models\StartFlowRequest;
use TencentCloud\Ess\V20201111\Models\CreateFlowSignUrlRequest;
use TencentCloud\Ess\V20201111\Models\CancelFlowRequest;
use TencentCloud\Ess\V20201111\Models\DescribeFlowInfoRequest;

// 腾讯电子文档
class TxEss{

    public $config = [];

    public function __construct($operatorUserId, $serverSignSealId)
    {
        $this->config = [
            'secretId'=>'AKIDwlPxTyNgppfOrfYPf6SfgV9qTHEB4tb9', // 调用API的secretId，通过腾讯云控制台获取
            'secretKey'=>'RfhYCdtxx64qQmwurdCar3ym9kEXlpX4', // 调用API的secretKey，通过腾讯云控制台获取
            // 'operatorUserId'=>'yDCdcUU53cznh4UEXKV7d8fT5LXyaXeg', // operatorUserId: 经办人Id，电子签控制台获取
            'operatorUserId'=>$operatorUserId,
            // 'serverSignSealId'=>'yDCdcUU5kdd02vUudgixHJvCvLhqBD2C', // 企业方静默签用的印章Id，电子签控制台获取
            'serverSignSealId'=>$serverSignSealId, // 企业方静默签用的印章Id，电子签控制台获取
            // 'templateId'=>'yDCYLUU5v3nc1jUqzfmxuBhJ6pT3jy8u', // 模板Id，电子签控制台获取，仅在通过模板发起时使用
            'endPoint'=>'ess.test.ess.tencent.cn', // API域名，现网使用 ess.tencentcloudapi.com
            'fileServiceEndPoint'=>'file.test.ess.tencent.cn', // 文件服务域名，现网使用 file.ess.tencent.cn
        ];
    }

    // 模版发起合同-创建签署流程
    public function createFlow($userinfo, $agent=0) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
             $cred = new Credential($this->config['secretId'], $this->config['secretKey']);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint("ess.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            $client = new EssClient($cred, "", $clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new CreateFlowRequest();

            $params = array(
                "Operator" => array(
                    "UserId" => $this->config['operatorUserId'],
                ),
                "FlowName" => "{$userinfo['name']}的劳动合同",
                "Approvers" => array(
                    array(
                        "ApproverType" => 3,
                        "OrganizationName" => $userinfo['company_name'],
                    ),
                    array(
                        "ApproverType" => 1,
                        "ApproverName" => $userinfo['name'],
                        "ApproverMobile" => $userinfo['mobile'],
                    )
                )

            );
           if ($agent) {
                $params['Agent'] = array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd");
           }
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个CreateFlowResponse的实例，与请求对象对应
            $resp = $client->CreateFlow($req);

            $result = [
                'code'=>0,
                'data'=>(array)$resp,
                'msg'=>'success',
            ];
            return $result;
        }
        catch(TencentCloudSDKException $e) {
            \think\Log::record($e->getMessage(), 'error');

            $result = [
                'code'=>1,
                'data'=>[],
                'msg'=>$e->getMessage(),
            ];
            return $result;
        }
    }

    // 模版发起合同-创建电子文档
    public function createTemplateDzwd($FormFields, $flowid, $templateId, $agent=0) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            $cred = new Credential($this->config['secretId'], $this->config['secretKey']);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint("ess.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            $client = new EssClient($cred, "ap-guangzhou", $clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new CreateDocumentRequest();

           $params = array(
                "Operator" => array(
                    "UserId" => $this->config['operatorUserId'],
                ),
                "TemplateId" => $templateId,
                "FlowId" => $flowid, //模版发起合同-创建签署流程接口生成
                "FormFields" => $FormFields,
                // "Agent" => array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd")
            );
           if ($agent) {
                $params['Agent'] = array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd");
           }
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个CreateDocumentResponse的实例，与请求对象对应
            $resp = $client->CreateDocument($req);

            $result = [
                'code'=>0,
                'data'=>(array)$resp,
                'msg'=>'success',
            ];
            return $result;
        }
        catch(TencentCloudSDKException $e) {
            \think\Log::record($e, 'error');
            $result = [
                'code'=>1,
                'data'=>[],
                'msg'=>$e->getMessage(),
            ];
            return $result;
        }
    }

    // 模版发起合同-发起签署流程
    public function startTemplateDzwd($flowid, $agent=0) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            $cred = new Credential($this->config['secretId'], $this->config['secretKey']);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint("ess.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            $client = new EssClient($cred, "ap-guangzhou", $clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new StartFlowRequest();

            $params = array(
                "Operator" => array(
                    "UserId" => $this->config['operatorUserId'],
                ),
                "FlowId" => $flowid
            );
           if ($agent) {
                $params['Agent'] = array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd");
           }
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个StartFlowResponse的实例，与请求对象对应
            $resp = $client->StartFlow($req);

            // 输出json格式的字符串回包

            $result = [
                'code'=>0,
                'data'=>(array)$resp,
                'msg'=>'success',
            ];
            return $result;
        }
        catch(TencentCloudSDKException $e) {
            \think\Log::record($e->getMessage(), 'error');
            $result = [
                'code'=>1,
                'data'=>[],
                'msg'=>$e->getMessage(),
            ];
            return $result;
        }
    }

    // 获取H5签署链接
    public function getH5Link($flowid, $userinfo, $agent=0) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            $cred = new Credential($this->config['secretId'], $this->config['secretKey']);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint("ess.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            $client = new EssClient($cred, "", $clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new CreateFlowSignUrlRequest();

            $params = array(
                "Operator" => array(
                        "UserId" => $this->config['operatorUserId'],
                ),
                "FlowId" => $flowid,
                "FlowApproverInfos" => array(
                    // array(
                    //     "ApproverType" => 1,
                    //     "ApproverName" => "张三",
                    //     "ApproverMobile" => "16553536961"
                    // )
                    array(
                        "ApproverType" => 1,
                        "ApproverName" => $userinfo['name'],
                        "ApproverMobile" => $userinfo['mobile']
                    )
                ),
            );
           if ($agent) {
                $params['Agent'] = array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd");
           }
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个CreateFlowSignUrlResponse的实例，与请求对象对应
            $resp = $client->CreateFlowSignUrl($req);

            $result = [
                'code'=>0,
                'data'=>(array)$resp,
                'msg'=>'success',
            ];
            return $result;
        }
        catch(TencentCloudSDKException $e) {
            \think\Log::record($e->getMessage(), 'error');
            $result = [
                'code'=>1,
                'data'=>[],
                'msg'=>$e->getMessage(),
            ];
            return $result;
        }
    }

    // 撤销单个合同流程
    public function cancelContract($flowid, $agent, $reason = "工资查询系统后台-管理员手动重新生成合同(此合同撤销)") {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            $cred = new Credential($this->config['secretId'], $this->config['secretKey']);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint("ess.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            $client = new EssClient($cred, "", $clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new CancelFlowRequest();

            $params = array(
                "Operator" => array(
                    "UserId" => $this->config['operatorUserId']
                ),
                "FlowId" => $flowid,
                "CancelMessage" => $reason
            );
           if ($agent) {
                $params['Agent'] = array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd");
           }
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个CancelFlowResponse的实例，与请求对象对应
            $resp = $client->CancelFlow($req);

            $result = [
                'code'=>0,
                'data'=>(array)$resp,
                'msg'=>'success',
            ];
            return $result;
        }
        catch(TencentCloudSDKException $e) {
            \think\Log::record($e->getMessage(), 'error');
            $result = [
                'code'=>1,
                'data'=>[],
                'msg'=>$e->getMessage(),
            ];
            return $result;
        }
    }

    // 查询合同流程的详情信息
    public function detailContract($flowIds_arr, $agent=0) {
        try {
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            $cred = new Credential($this->config['secretId'], $this->config['secretKey']);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint("ess.tencentcloudapi.com");

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            $client = new EssClient($cred, "", $clientProfile);

            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new DescribeFlowInfoRequest();

            $params = array(
                "Operator" => array(
                    "UserId" => $this->config['operatorUserId']
                ),
                "FlowIds" => $flowIds_arr
            );
           if ($agent) {
                $params['Agent'] = array("ProxyOrganizationId" => "yDCdnUU5oqdeahUyjIbfpEqYKlCxcINd");
           }
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个DescribeFlowInfoResponse的实例，与请求对象对应
            $resp = $client->DescribeFlowInfo($req);

            $result = [
                'code'=>0,
                'data'=>(array)$resp,
                'msg'=>'success',
            ];
            return $result;
        }
        catch(TencentCloudSDKException $e) {
            \think\Log::record($e->getMessage(), 'error');
            $result = [
                'code'=>1,
                'data'=>[],
                'msg'=>$e->getMessage(),
            ];
            return $result;
        }
    }

    // 合同状态
    public function getContractStatus($status) {
        $status_arr = [
            0=>'未开启流程(合同中不存在填写环节)',
            1=>'待签署',
            2=>'部分签署',
            3=>'已拒签',
            4=>'已签署',
            5=>'已过期',
            6=>'已撤销',
            7=>'未开启流程(合同中存在填写环节)',
            8=>'等待填写',
            9=>'部分填写',
            10=>'已拒填',
            21=>'已解除',
        ];

        return isset($status_arr[$status]) ? $status_arr[$status] : '';
    }
}
